package com.codesuc.aichat.interceptor;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.convert.Convert;
import com.codesuc.aichat.common.Result;
import com.codesuc.aichat.enums.CodeSucErrorEnum;
import com.codesuc.aichat.utils.CommonUtil;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.Builder;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
 * @Description 登录拦截器
 * @Author Mr.Zhang
 * @Date 2025/8/5 12:26
 * @Version 1.0
 */
@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {

    public static ThreadLocal<LoginUser> threadLocalContext = new ThreadLocal<>();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 检查是否登录
        StpUtil.checkLogin();
        long userId = StpUtil.getLoginIdAsLong();

        if (userId == 0L) {
            CommonUtil.sendJsonMessage(response, Result.buildResult(CodeSucErrorEnum.ACCOUNT_UNLOGIN));
            return false;
        }

        // 构建登录用户
        LoginUser loginUser = LoginUser.builder()
                .mail(Convert.toStr(StpUtil.getExtra("mail")))
                .nickname(Convert.toStr(StpUtil.getExtra("username")))
                .username(Convert.toStr(StpUtil.getExtra("username")))
                .id(userId)
                .build();
        log.info("当前登录用户：{}", loginUser);
        threadLocalContext.set(loginUser);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 请求处理完成了清除存储的用户信息，防止内存泄漏
        log.info("userId=[{}]请求完成，清理用户数据", threadLocalContext.get().getId());
        threadLocalContext.remove();
    }

    @Data
    @Builder
    @Schema(title = "登录用户", description = "登录用户信息")
    public static class LoginUser {
        /**主键*/
        @Schema(name = "用户 ID")
        @JsonSerialize(using = ToStringSerializer.class)
        private Long id;
        /**用户名*/
        @Schema(name = "用户名")
        private String username;
        /**昵称*/
        @Schema(name = "昵称")
        private String nickname;
        /**邮箱*/
        @Schema(name = "邮箱")
        private String mail;
    }

}
